package evm

import (
	"fmt"

	"github.com/golang/protobuf/proto"
	"hundsun.com/hsl/hschain/contract/evm/types"
	ecom "hundsun.com/hsl/hschain/executor/common"
	"hundsun.com/hsl/hschain/protos/execute"
	pbledger "hundsun.com/hsl/hschain/protos/ledger"
	pbtypes "hundsun.com/hsl/hschain/protos/types"
)

// Query 查询部分
func (e *Evm) Query(ctx *ecom.ExecContent, funcName string, param []byte) (proto.Message, error) {
	switch funcName {
	case types.QueryEVMContract:
		return e.queryContract(ctx, param)
	case types.QueryEstimateGas:
		return e.queryEstimateGas(ctx, param)
	default:
		return nil, fmt.Errorf("%s not implemented", funcName)
	}
}

func (e *Evm) queryEstimateGas(ctx *ecom.ExecContent, param []byte) (proto.Message, error) {
	_, usedGas, err := execQuery(ctx, param)
	if err != nil {
		return nil, err
	}
	return &pbtypes.Uint64{I: usedGas}, nil
}

func (e *Evm) queryContract(ctx *ecom.ExecContent, param []byte) (proto.Message, error) {
	receipt, _, err := execQuery(ctx, param)
	return receipt, err
}

func execQuery(ctx *ecom.ExecContent, param []byte) (*pbledger.TransactionReceipt, uint64, error) {
	var tx = &pbledger.Transaction{}
	err := proto.Unmarshal(param, tx)
	if err != nil {
		return nil, 0, err
	}
	tx.Fee = types.DefaultQueryGasLimit * 1 // 查询时候尽可能传入一个较大gas防止gas消耗完
	receipt := &pbledger.TransactionReceipt{
		TxStatus: pbledger.TransactionReceipt_SUCCESSFUL,
	}
	gtx := &execute.GroupedTransaction{
		Tx:        tx,
		TxExecRst: &pbledger.TransactionExecResult{Receipt: receipt},
	}
	_, usedGas, err := exec(ctx, gtx, true)
	return receipt, usedGas, err
}
